package com.gzc;

import com.gzc.pojo.*;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.codecs.configuration.CodecProvider;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import org.bson.types.ObjectId;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;

import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;

/**
 * Created by Spirit_wolf on 2018/9/30.
 */
public class MongoDBDriverQuickStart02 {

    public MongoDBDriverQuickStart02() {
        // Create a CodecRegistry containing the PojoCodecProvider instance.
        CodecProvider pojoCodecProvider = PojoCodecProvider.
                builder().
                //注册POJO对象的整个包
                register("com.gzc.pojo").
                automatic(true).
                build();
        CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
                fromProviders(pojoCodecProvider));

        //为了使用3.5新加的POJO codec
//        CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
//                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        //实例化MongoClient对象时,设置pojoCodecRegistry
//        MongoClient mongoClient = new MongoClient("localhost", MongoClientOptions.
//                builder().
//                codecRegistry(pojoCodecRegistry).
//                build());
        //连接副本集
        MongoClient mongoClient = new MongoClient(
                Arrays.asList(new ServerAddress("localhost", 27111),
                        new ServerAddress("localhost", 27112),
                        new ServerAddress("localhost", 27113)),
                MongoClientOptions.
                        builder().
                        codecRegistry(pojoCodecRegistry).
                        build());

        //指定数据库,如果不存在则会新建该库
        MongoDatabase database = mongoClient.getDatabase("inDriver3_8_2");
        /*
        //将POJO插入MongoDB
//        在将POJO插入MongoDB之前，需要MongoCollection使用Pojo类型配置的实例：
        MongoCollection<Person> collection = database.getCollection("people", Person.class);

        //插入一个人,要将Person插入集合，可以使用集合的insertOne()方法。
        Person ada = new Person("Ada Byron", 20, new Address("St James Square", "London", "W1"));
        collection.insertOne(ada);
//        插入很多人
//        要添加多个Person实例，可以使用集合的insertMany()方法来获取列表Person。
        List<Person> people = Arrays.asList(
                new Person("Charles Babbage", 45, new Address("5 Devonshire Street", "London", "W11")),
                new Person("Alan Turing", 28, new Address("Bletchley Hall", "Bletchley Park", "MK12")),
                new Person("Timothy Berners-Lee", 61, new Address("Colehill", "Wimborne", null))
        );
        collection.insertMany(people);

        //查询集合
//        要查询集合，可以使用集合的find()方法。
        Block<Person> printBlock = new Block<Person>() {
            @Override
            public void apply(final Person person) {
                System.out.println(person);
            }
        };
        collection.find().forEach(printBlock);
         */

        {
            MongoCollection<Player> playerCollection = database.getCollection("player", Player.class);

            //--------------物品----------------------
            Goods goods1 = new Goods(UUID.randomUUID().toString().hashCode(), 100, 48);
            Goods goods2 = new Goods(UUID.randomUUID().toString().hashCode(), 101, 11);
            Goods goods3 = new Goods(UUID.randomUUID().toString().hashCode(), 102, 123);

            BagItemInfo bagItemInfo = new BagItemInfo();
            bagItemInfo.getGoodsGuid2goods().put(goods1.getGoodsGuid() + "", goods1);
            bagItemInfo.getGoodsGuid2goods().put(goods2.getGoodsGuid() + "", goods2);
            bagItemInfo.getGoodsGuid2goods().put(goods3.getGoodsGuid() + "", goods3);

            //--------------装备----------------------
            Goods equip1 = new Goods(UUID.randomUUID().toString().hashCode(), 200, 123);
            Goods equip2 = new Goods(UUID.randomUUID().toString().hashCode(), 201, 312);
            Goods equip3 = new Goods(UUID.randomUUID().toString().hashCode(), 202, 2221);
            BagItemInfo equipBag = new BagItemInfo();
            equipBag.getGoodsGuid2goods().put(equip1.getGoodsGuid() + "", equip1);
            equipBag.getGoodsGuid2goods().put(equip2.getGoodsGuid() + "", equip2);
            equipBag.getGoodsGuid2goods().put(equip3.getGoodsGuid() + "", equip3);

            ArrayList<Address> addresses = new ArrayList<>();
            Address address1 = new Address("street111","city111","zip111");
            Address address2 = new Address("street222","city222","zip333");
            Address address3 = new Address("street333","city333","zip333");
            addresses.add(address1);
            addresses.add(address2);
            addresses.add(address3);


            BagInfo bagInfo = new BagInfo();
//            bagInfo.getBagType2bagItem().put(BagType.Goods, bagItemInfo);
//            bagInfo.getBagType2bagItem().put(BagType.Equip, equipBag);
            bagInfo.getBagType2bagItem().put(BagType.Goods.name(), bagItemInfo);
            bagInfo.getBagType2bagItem().put(BagType.Equip.name(), equipBag);

            Player player = new Player(System.currentTimeMillis(),
                    "QQ",
                    System.currentTimeMillis(),
                    "NAME" + System.currentTimeMillis(),
                    Math.abs(UUID.randomUUID().toString().hashCode()),
                    Math.abs(UUID.randomUUID().toString().hashCode()),
                    bagInfo,
                    addresses);

            playerCollection.insertOne(player);
        }
    }

    //region-------------------------New in 3.5--------------------------------------

    //region-------------Quick Start - POJOs-------------

    public static final class Person {
        private ObjectId id;
        private String name;
        private int age;
        private Address address;

        public Person() {
        }

        public Person(String name, int age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }

        public ObjectId getId() {
            return id;
        }

        public void setId(final ObjectId id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(final int age) {
            this.age = age;
        }

        public Address getAddress() {
            return address;
        }

        public void setAddress(final Address address) {
            this.address = address;
        }

        // Rest of implementation


        @Override
        public String toString() {
            return "Person{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    ", address=" + address +
                    '}';
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Person person = (Person) o;

            if (age != person.age) return false;
            if (!id.equals(person.id)) return false;
            if (!name.equals(person.name)) return false;
            return address.equals(person.address);
        }

        @Override
        public int hashCode() {
            int result = id.hashCode();
            result = 31 * result + name.hashCode();
            result = 31 * result + age;
            result = 31 * result + address.hashCode();
            return result;
        }
    }

    //endregion-------------Quick Start - POJOs-------------

    //endregion-------------------------New in 3.5--------------------------------------

}
